/*
* @Author: baidwwy
* @Date:   2019-04-09 00:20:53
* @Last Modified by:   baidwwy
* @Last Modified time: 2020-05-17 01:17:16
*/
#include "gge.h"
#include <SDL_image.h>
//IMG_Linked_Version
static int	LUA_IMG_Init(lua_State *L)
{
	int flags = (int)luaL_optinteger(L, 1,IMG_INIT_JPG|IMG_INIT_PNG|IMG_INIT_TIF|IMG_INIT_WEBP);
	lua_pushboolean(L,IMG_Init(flags)!=0);
	return 1;
}

static int	LUA_IMG_Quit(lua_State *L)
{
	IMG_Quit();
	return 0;
}

static int	LUA_IMG_LoadTyped_RW(lua_State *L)
{
	SDL_RWops * ops = *(SDL_RWops**)luaL_checkudata(L, 1, "SDL_RWops");
	const char *type = luaL_checkstring(L,2);
	SDL_Surface *r = IMG_LoadTyped_RW(ops,0,type);
	if (r){
		SDL_Surface **ud = (SDL_Surface**)lua_newuserdata(L, sizeof (SDL_Surface*));
		*ud = r;
		luaL_setmetatable(L, "SDL_Surface");
		return 1;
	}
	return 0;
}

static int	LUA_IMG_Load(lua_State *L)
{
	const char *path = luaL_checkstring(L, 1);
	SDL_Surface *sf = IMG_Load(path);
	if (sf){
		SDL_Surface **ud = (SDL_Surface**)lua_newuserdata(L, sizeof (SDL_Surface*));
		*ud = sf;
		luaL_setmetatable(L, "SDL_Surface");
		return 1;
	}
	return 0;
}

static int	LUA_IMG_LoadARGB8888(lua_State *L)
{
	const char *path = luaL_checkstring(L, 1);
	Uint32 key = (Uint32)luaL_optinteger(L, 2, 0);
	SDL_Surface *sf = IMG_Load(path);
	
	if (sf){
		if (sf->format->format != SDL_PIXELFORMAT_ARGB8888){
			SDL_Surface *temp = SDL_ConvertSurfaceFormat(sf,SDL_PIXELFORMAT_ARGB8888,SDL_SWSURFACE);
			if (key != 0)
				SDL_SetColorKey(temp, SDL_TRUE, key);
			if(temp){
				SDL_FreeSurface(sf);
				sf=temp;
			}
		}
		SDL_Surface** ud = (SDL_Surface**)lua_newuserdata(L, sizeof (SDL_Surface*));
		*ud = sf;
		luaL_setmetatable(L, "SDL_Surface");
		return 1;
	}
	return 0;
}

static int	LUA_IMG_Load_RW(lua_State *L)
{
	SDL_RWops * ops = *(SDL_RWops**)luaL_checkudata(L, 1, "SDL_RWops");
	SDL_Surface *sf = IMG_Load_RW(ops, 0);
	if (sf){
		SDL_Surface **ud = (SDL_Surface**)lua_newuserdata(L, sizeof (SDL_Surface*));
		*ud = sf;
		luaL_setmetatable(L, "SDL_Surface");
		return 1;
	}
	return 0;
}

static int	LUA_IMG_LoadARGB8888_RW(lua_State *L)
{
	SDL_RWops * ops = *(SDL_RWops**)luaL_checkudata(L, 1, "SDL_RWops");
	SDL_Surface *sf = IMG_Load_RW(ops, 0);

	if (sf){
		if (sf->format->format != SDL_PIXELFORMAT_ARGB8888){
			SDL_Surface *temp = SDL_ConvertSurfaceFormat(sf,SDL_PIXELFORMAT_ARGB8888,SDL_SWSURFACE);
			if(temp){
				SDL_FreeSurface(sf);
				sf=temp;
			}
		}
		SDL_Surface** ud = (SDL_Surface**)lua_newuserdata(L, sizeof (SDL_Surface*));
		*ud = sf;
		luaL_setmetatable(L, "SDL_Surface");
		return 1;
	}
	return 0;
}

static int	LUA_IMG_LoadTexture(lua_State *L)
{
	SDL_Renderer * rd = *(SDL_Renderer**)luaL_checkudata(L, 1, "SDL_Renderer");
	const char *file = luaL_checkstring(L,2);
	int access = (int)luaL_optinteger(L,3,SDL_TEXTUREACCESS_STATIC);

	SDL_Texture *tex = NULL;
	SDL_Surface *surface = IMG_Load(file);
	if (surface){
		if (surface->format->format != SDL_PIXELFORMAT_ARGB8888){
			SDL_Surface *temp = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888, SDL_SWSURFACE);
			SDL_FreeSurface(surface);
			surface = temp;
		}
		tex = SDL_CreateTexture(rd, SDL_PIXELFORMAT_ARGB8888, access, surface->w, surface->h);
		SDL_UpdateTexture(tex, NULL, surface->pixels, surface->pitch);
		SDL_FreeSurface(surface);
	}
	if (tex){
		GGE_Texture *ud = (GGE_Texture*)lua_newuserdata(L, sizeof (GGE_Texture));
		SDL_memset(ud,0,sizeof (GGE_Texture));
		ud->tex = tex;
		SDL_SetTextureBlendMode(tex,SDL_BLENDMODE_BLEND);
		luaL_setmetatable(L, "SDL_Texture");
		return 1;
	}
	return 0;
}

static int	LUA_IMG_LoadTexture_RW(lua_State *L)
{
	SDL_Renderer * rd = *(SDL_Renderer**)luaL_checkudata(L, 1, "SDL_Renderer");
	SDL_RWops * ops = *(SDL_RWops**)luaL_checkudata(L, 2, "SDL_RWops");
	int access = (int)luaL_optinteger(L,3,SDL_TEXTUREACCESS_STATIC);

	SDL_Texture *tex = NULL;
	SDL_Surface *surface = IMG_Load_RW(ops,0);
	if (surface){
		if (surface->format->format != SDL_PIXELFORMAT_ARGB8888)
		{
			SDL_Surface *temp = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888, SDL_SWSURFACE);
			if (temp) {
				tex = SDL_CreateTexture(rd, SDL_PIXELFORMAT_ARGB8888, access,temp->w, temp->h);
				SDL_UpdateTexture(tex, NULL, temp->pixels, temp->pitch);
				SDL_FreeSurface(temp);
			}
		}else{
			tex = SDL_CreateTexture(rd, SDL_PIXELFORMAT_ARGB8888, access,surface->w, surface->h);
			SDL_UpdateTexture(tex, NULL, surface->pixels, surface->pitch);
		}
		SDL_FreeSurface(surface);
	}
	if (tex)
	{
		GGE_Texture *ud = (GGE_Texture*)lua_newuserdata(L, sizeof (GGE_Texture));
		SDL_memset(ud,0,sizeof (GGE_Texture));
		ud->tex = tex;
		SDL_SetTextureBlendMode(tex,SDL_BLENDMODE_BLEND);
		luaL_setmetatable(L, "SDL_Texture");
		return 1;
	}
	return 0;
}

static int	LUA_IMG_LoadTextureTyped_RW(lua_State *L)
{
	SDL_Renderer * rd = *(SDL_Renderer**)luaL_checkudata(L, 1, "SDL_Renderer");
	SDL_RWops * ops = *(SDL_RWops**)luaL_checkudata(L, 2, "SDL_RWops");
	const char *type = luaL_checkstring(L,3);
	SDL_Texture *tex = IMG_LoadTextureTyped_RW(rd,ops,0,type);
	if (tex){
		GGE_Texture *ud = (GGE_Texture*)lua_newuserdata(L, sizeof (GGE_Texture));
		SDL_memset(ud,0,sizeof (GGE_Texture));
		ud->tex;
		luaL_setmetatable(L, "SDL_Texture");
		return 1;
	}
	return 0;
}

static int	LUA_IMG_SavePNG(lua_State *L)
{
	SDL_Surface * sf = *(SDL_Surface**)luaL_checkudata(L, 1, "SDL_Surface");
	const char *file = luaL_checkstring(L,2);
	lua_pushboolean(L,IMG_SavePNG(sf,file));
	
	return 1;
}
static int	LUA_IMG_SavePNG_RW(lua_State *L)
{
	SDL_Surface * sf = *(SDL_Surface**)luaL_checkudata(L, 1, "SDL_Surface");
	SDL_RWops * ops = *(SDL_RWops**)luaL_checkudata(L, 2, "SDL_RWops");
	int freesrc = (int)luaL_optinteger(L,3,0);
	lua_pushboolean(L,IMG_SavePNG_RW(sf,ops,freesrc));
	return 1;
}

static int	LUA_IMG_SaveJPG(lua_State *L)
{
	SDL_Surface * sf = *(SDL_Surface**)luaL_checkudata(L, 1, "SDL_Surface");
	const char *file = luaL_checkstring(L,2);
	int quality = (int)luaL_optinteger(L,3,90);
	lua_pushboolean(L,IMG_SaveJPG(sf,file,quality));
	return 1;
}

static int	LUA_IMG_SaveJPG_RW(lua_State *L)
{
	SDL_Surface * sf = *(SDL_Surface**)luaL_checkudata(L, 1, "SDL_Surface");
	SDL_RWops * ops = *(SDL_RWops**)luaL_checkudata(L, 2, "SDL_RWops");
	int freesrc = (int)luaL_optinteger(L,3,0);
	int quality = (int)luaL_checkinteger(L,3);
	lua_pushboolean(L,IMG_SaveJPG_RW(sf,ops,freesrc,quality));
	return 1;
}

static const luaL_Reg IMG_Renderer_Meta[] = {
	{"LoadTexture"         , LUA_IMG_LoadTexture}         ,
	{"LoadTexture_RW"      , LUA_IMG_LoadTexture_RW}      ,
	{"LoadTextureTyped_RW" , LUA_IMG_LoadTextureTyped_RW} ,
	{ NULL                 , NULL			}
};
static const luaL_Reg IMG_Surface_Meta[] = {
	{"SavePNG"    , LUA_IMG_SavePNG}    ,
	{"SavePNG_RW" , LUA_IMG_SavePNG_RW} ,
	{"SaveJPG"    , LUA_IMG_SaveJPG}    ,
	{"SaveJPG_RW" , LUA_IMG_SaveJPG_RW} ,
	{ NULL        , NULL			}
};
static const luaL_Reg IMG_Funcs[] = {
	{"Init"         , LUA_IMG_Init}         ,
	{"Quit"         , LUA_IMG_Quit}         ,
	{"Load"         , LUA_IMG_Load}         ,
	{"LoadARGB8888"         , LUA_IMG_LoadARGB8888}         ,
	{"LoadARGB8888_RW"         , LUA_IMG_LoadARGB8888_RW}         ,
	
	
	{"Load_RW"      , LUA_IMG_Load_RW}      ,
	{"LoadTyped_RW" , LUA_IMG_LoadTyped_RW} ,
	{ NULL          , NULL			}
};
__declspec(dllexport) int luaopen_gsdl2_image(lua_State *L)
{
	luaL_getmetatable(L,"SDL_Renderer");
	luaL_setfuncs(L,IMG_Renderer_Meta,0);
	lua_pop(L, 1);
	luaL_getmetatable(L,"SDL_Surface");
	luaL_setfuncs(L,IMG_Surface_Meta,0);
	lua_pop(L, 1);

	luaL_newlib(L,IMG_Funcs);
	return 1;
}
//IMG_isICO
//IMG_isCUR
//IMG_isBMP
//IMG_isGIF
//IMG_isJPG
//IMG_isLBM
//IMG_isPCX
//IMG_isPNG
//IMG_isPNM
//IMG_isSVG
//IMG_isTIF
//IMG_isXCF
//IMG_isXPM
//IMG_isXV
//IMG_isWEBP

//IMG_LoadICO_RW
//IMG_LoadCUR_RW
//IMG_LoadBMP_RW
//IMG_LoadGIF_RW
//IMG_LoadJPG_RW
//IMG_LoadLBM_RW
//IMG_LoadPCX_RW
//IMG_LoadPNG_RW
//IMG_LoadPNM_RW
//IMG_LoadSVG_RW
//IMG_LoadTGA_RW
//IMG_LoadTIF_RW
//IMG_LoadXCF_RW
//IMG_LoadXPM_RW
//IMG_LoadXV_RW
//IMG_LoadWEBP_RW

//IMG_ReadXPMFromArray